#include "qrreader.h"

using namespace std;

qrReader::qrReader()
{

}

void qrReader::readQrCode(QImage* img)
{
    for (int i = 0; i < 5; i++)
        seed[i] = 18+4*i;
    for (int i = 0; i < 7; i++)
    {
        seed2[i][0] = 6;
        seed2[i][1] = 22+2*i;
        seed2[i][2] = 38+4*i;
    }

    cout << "\nTAMANHO DA IMAGEM = " << img->width() << "," << img->height();
    pixelProportion = determinePixelProportion(img);
    cout << "\nTAMANHO EQUIVALENTE DO PIXEL = " << pixelProportion;
    vector<center> finalCenterList = findCenters(img);
    if (finalCenterList.size() >= 3)
    {
        selectBestCenters(finalCenterList);
        for (int row = 0; row < 8*pixelProportion; row += pixelProportion)
        {
            for (int col = 0; col < 8*pixelProportion; col += pixelProportion)
            {
                paintPixel(upperLeftCenter.getRow()-3*pixelProportion+row, upperLeftCenter.getCollumn()-3*pixelProportion+col, qRgb(0,255,0), img);
                paintPixel(upperRightCenter.getRow()-3*pixelProportion+row, upperRightCenter.getCollumn()-4*pixelProportion+col, qRgb(0,255,0), img);
                paintPixel(lowerLeftCenter.getRow()-4*pixelProportion+row, lowerLeftCenter.getCollumn()-3*pixelProportion+col, qRgb(0,255,0), img);
            }
        }
        virtualOriginRow = upperLeftCenter.getRow()-3*pixelProportion;
        virtualOriginCol = upperLeftCenter.getCollumn()-3*pixelProportion;
        rowTimming = upperLeftCenter.getRow()+3*pixelProportion;
        colTimming = upperLeftCenter.getCollumn()+3*pixelProportion;
        //findQuietZone(upperLeftCenter, upperRightCenter, lowerLeftCenter, img);
        versionINFO = checkVersion(upperLeftCenter, upperRightCenter, lowerLeftCenter, img);
        cout << "\nVERSAO = " << versionINFO;
        findFormat(upperLeftCenter, lowerLeftCenter, upperRightCenter, img);
        cout << "\nECC LEVEL = " << eccLevel;
        cout << "\nMASCARA = " << maskPatern;
        if (versionINFO > 1)
            findAlignments(upperLeftCenter, img);
        dataBlocks = getDataBlocks(lowerLeftCenter, img);
        cout << "\nNUMERO DE BYTES = " << dataBlocks.size();
        //for (int i = 0; i < dataBlocks.size(); i++)
            //cout << "\nBLOCO " << i+1 << " = " << dataBlocks.at(i);
        String data = decodeDataBlocks();
        cout << "\nDATA = " << data;
        cout << "\n==================================";
    }
}

int qrReader::determinePixelProportion(QImage* img)
{
    int proportion = img->width();
    int propAux = 0;
    int middle = img->width()/2;
    for (int row = 0; row < img->height()-1; row++)
    {
        if (isPixelBlack(row, middle, img))
            propAux++;
        else
        {
            if (proportion > propAux && propAux != 0)
                proportion = propAux;
            propAux = 0;
        }
    }

    int proportion2 = img->width();
        propAux = 0;
        for (int row = 0; row < img->height()-1; row++)
        {
            if (!isPixelBlack(row, middle, img))
                propAux++;
            else
            {
                if (proportion2 > propAux && propAux != 0)
                    proportion2 = propAux;
                propAux = 0;
            }
        }

        if (proportion < proportion2)
            return proportion;
        else
            return proportion2;
    return proportion;
}

vector<center> qrReader::findCenters(QImage* img)
{
    vector<center> centerList = findPossibleCenters(img);
    if (centerList.size() == 0)
        return centerList;
    vector<groupCenter> groupList;
    center* c =& centerList.at(0);
    groupCenter g;
    g.add(*c);
    (*c).addToGroup(1);
    groupList.push_back(g);
    //free(c);
    for (int i = 0; i < centerList.size(); i++)
    {
        center* c1 =& centerList.at(i);
        //cout << "\nCentro em linha = " << (*c1).getRow() << " e coluna = " << (*c1).getCollumn();
        for (int j = 0; j < i; j++)
        {
            center* c2 =& centerList.at(j);
            if ((*c1).getCollumn() == (*c2).getCollumn())
            {
                int distance = abs((*c1).getRow()-(*c2).getRow());
                //cout << "\n- Distancia ao centro " << (*c2).getRow() << "," << (*c2).getCollumn() << " = " << distance;
                if (distance <= 3)
                {
                    //cout << "\nMENOR DISTANCIA";
                    groupCenter* gc =& groupList.at((*c2).getGroupNumber()-1);
                    (*gc).add(*c1);
                    (*c1).addToGroup((*c2).getGroupNumber());
                    //free(gc);
                    break;
                }
            }
            //free(c2);
        }
        if ((*c1).getGroupNumber() == 0)
        {
            //cout << "\nNOVO GRUPO";
            groupCenter newgc;
            newgc.add(*c1);
            (*c1).addToGroup(groupList.size()+1);
            groupList.push_back(newgc);
        }
        //cout << "\nVai para o grupo = " << (*c1).getGroupNumber();
        //free(c1);
    }

    vector<center> finalCenterList;
    for (int i = 0; i < groupList.size(); i++)  {
        groupCenter gc = groupList.at(i);
        //cout << "\nGrupo " << i+1;
        int total = 0;
        for (int j = 0; j < gc.size(); j++)
        {
            //cout << "\nCentro " << gc.get(j).getRow() << "," << gc.get(j).getCollumn();
            total += gc.get(j).getRow();
        }
        int media = total/gc.size();
        //cout << "\n-Centro Final = " << media << "," << gc.get(0).getCollumn();

        // add every possible center to a finalList, in that 3 of them will be selected
        center c;
        c.addCenter(media,gc.get(0).getCollumn());
        finalCenterList.push_back(c);
    }

    return finalCenterList;
}

/**  Selects which centers should be selected as being the ones from the finder pattern
 *  @params vector<center> finalCentersList
 *  @returns vector <center>
 */
void qrReader::selectBestCenters(vector<center> finalCentersList)
{
    upperLeftCenter = finalCentersList.at(0);

    int  centerValue   = upperLeftCenter.getRow() + upperLeftCenter.getCollumn();
    for (int i = 1; i < finalCentersList.size(); i++) {

        center smallestEvaluatedCenter = finalCentersList.at(i);

        upperLeftCenter = (smallestEvaluatedCenter.getRow() + smallestEvaluatedCenter.getCollumn() < centerValue)
                          ? smallestEvaluatedCenter : upperLeftCenter;
    }

    upperRightCenter = lowerLeftCenter = upperLeftCenter; // initialize  upperRight & lowerLeft Centers with the upperLeft (smallest) value

    cout << "\nCENTRO DA ESQ-CIMA: (" << upperLeftCenter.getRow() << "," << upperLeftCenter.getCollumn() << ")";

    centerValue = 0;
    for (int i = 0; i < finalCentersList.size(); i++) {

        center xAlignedCenter = finalCentersList.at(i);

        if (xAlignedCenter.getRow() == upperRightCenter.getRow()) {

            upperRightCenter = (upperRightCenter.getRow() + upperRightCenter.getCollumn() >= centerValue)
                               ? xAlignedCenter : upperRightCenter;

            centerValue = xAlignedCenter.getRow() + xAlignedCenter.getCollumn();
        }
    }

    cout << "\nCENTRO DA DIR-CIMA: (" << upperRightCenter.getRow() << "," << upperRightCenter.getCollumn() << ")";

    centerValue = 0;
    for (int i = 0; i < finalCentersList.size(); i++) {

        center yAlignedCenter = finalCentersList.at(i);

        if (yAlignedCenter.getCollumn() == lowerLeftCenter.getCollumn()) {

            lowerLeftCenter = (lowerLeftCenter.getRow() + lowerLeftCenter.getCollumn() >= centerValue)
                               ? yAlignedCenter : lowerLeftCenter;

             centerValue = yAlignedCenter.getRow() + yAlignedCenter.getCollumn();
        }
    }

    cout << "\nCENTRO DA ESQ-BAIX: (" << lowerLeftCenter.getRow() << "," << lowerLeftCenter.getCollumn() << ")";
}

vector<center> qrReader::findPossibleCenters(QImage* img)
{

    vector<center> centerList;

    checkHorizontal(0, img->height()-1, img, &centerList);

    //checkHorizontal(0, pixelProportion*8, img, &centerList);

    //checkHorizontal(img->height()-pixelProportion*8, img->height(), img, &centerList);

    if (centerList.size() > 0)
        cout << "\nNUMERO DE CENTROS ENCONTRADOS = " << centerList.size();

    return centerList;
}

void qrReader::checkHorizontal(int rowStart, int rowLimit, QImage *img, vector<center> *centerList)
{
    int stateCount[5] = {0};
    int currentState = 0;

    for(int row = rowStart; row < rowLimit; row++)
    {
        stateCount[0] = 0;
        stateCount[1] = 0;
        stateCount[2] = 0;
        stateCount[3] = 0;
        stateCount[4] = 0;
        currentState = 0;

        for (int col = 0; col < img->width(); col++)
        {
            if(isPixelBlack(row, col, img))
            {
                // We're at a black pixel
                if((currentState & 0x1)==1)
                {
                    // We were counting white pixels
                    // So change the state now
                    // W->B transition
                    currentState++;
                }
                // Works for boths W->B and B->B
                stateCount[currentState]++;
            }
            else
            {
                // We got to a white pixel...
                if((currentState & 0x1)==1)
                {
                    // W->W change
                    stateCount[currentState]++;
                }
                else
                {
                    // ...but, we were counting black pixels
                    if(currentState==4)
                    {
                        // We found the 'white' area AFTER the finder patter
                        // Do processing for it here
                        if(checkRatio(stateCount))
                        {
                            int total = 0;
                            for (int i = 0; i < 5; i++)
                            {
                                total += stateCount[i];
                            }
                            if (crossCheckVertical(row - total/2, col - total/2, img))
                            {
                                int middle = (2*col-total)/2;
                                center c;
                                c.addCenter(row, middle);
                                centerList->push_back(c);
                            }
                        }
                        else
                        {
                            currentState  = 3;
                            stateCount[0] = stateCount[2];
                            stateCount[1] = stateCount[3];
                            stateCount[2] = stateCount[4];
                            stateCount[3] = 1;
                            stateCount[4] = 0;
                            continue;
                        }
                        currentState  = 0;
                        stateCount[0] = 0;
                        stateCount[1] = 0;
                        stateCount[2] = 0;
                        stateCount[3] = 0;
                        stateCount[4] = 0;
                    }
                    else
                    {
                        // We still haven't go 'out' of the finder pattern yet
                        // So increment the state
                        // B->W transition
                        currentState++;
                        stateCount[currentState]++;
                    }
                } // fim do else if((currentState & 0x1)==1
            } // fim do else if(ptr[col]<128)
        }  // fim for da coluna
    } // fim do for da linha
}

bool qrReader::crossCheckVertical(int startRow, int startCol, QImage* img)
{
    int currentState = 0;
    int stateCount[5] = {0};
    for (int row = 0; row <= startCol*2; row++)
    {
        if (row + startRow > img->height()-1 || row + startRow < 0) {
            return false;
        }

        if(isPixelBlack(row + startRow, startCol, img))
        {
            if((currentState & 0x1)==1)
            {
                currentState++;
            }
            stateCount[currentState]++;
        }
        else
        {
            if((currentState & 0x1)==1)
            {
                stateCount[currentState]++;
            }
            else
            {
                if(currentState==4)
                {
                    if(checkRatio(stateCount))
                        return true;
                }
                else
                {
                    currentState++;
                    stateCount[currentState]++;
                }
            }
        }
    }
    return false;
}

bool qrReader::checkRatio(int stateCount[])
{
    int totalFinderSize = 0;
    for(int i=0; i<5; i++)
    {
        int count = stateCount[i];
        totalFinderSize += count;
        if(count==0)
            return false;
    }
    if(totalFinderSize<7)
        return false;
    // Calculate the size of one module
    int moduleSize = ceil(totalFinderSize / 7.0);
    int maxVariance = moduleSize/2;
    bool retVal= ((abs(moduleSize - (stateCount[0])) < maxVariance) &&
        (abs(moduleSize - (stateCount[1])) < maxVariance) &&
        (abs(3*moduleSize - (stateCount[2])) < 3*maxVariance) &&
        (abs(moduleSize - (stateCount[3])) < maxVariance) &&
        (abs(moduleSize - (stateCount[4])) < maxVariance));
    return retVal;
}

int qrReader::checkVersion(center c1, center c2, center c3, QImage* img)
{
    int dimension = c2.getCollumn()-c1.getCollumn()+6*pixelProportion;
    int version = (dimension-(17*pixelProportion))/(4*pixelProportion);
    version++;
    if (version > 6)
        version = checkExactVersion(c2,c3,img);
    return version;
}

int qrReader::checkExactVersion(center c1, center c2, QImage* img)
{
    int version = 0;
    int counter = 17;

    for (int row = 0; row < 6*pixelProportion; row += pixelProportion)
    {
        for (int col = 0; col < 3*pixelProportion; col += pixelProportion)
        {
            if (isPixelBlack(c1.getRow()-(3*pixelProportion)+row,c1.getCollumn()-(7*pixelProportion)+col,img))
                version += 1 << counter;
            counter--;
            paintPixel(c1.getRow()-(3*pixelProportion)+row, c1.getCollumn()-(7*pixelProportion)+col, qRgb(32,255,200), img);
        }
    }

    for (int col = 0; col < 6*pixelProportion; col += pixelProportion)
        for (int row = 0; row < 3*pixelProportion; row += pixelProportion)
            paintPixel(c2.getRow()-(7*pixelProportion)+row, c2.getCollumn()-(3*pixelProportion)+col, qRgb(32,255,200), img);

    switch (version) {
        case 42232:  // 001010010011111000
            return 7;
            break;
        case 63108:  // 001111011010000100
            return 8;
            break;
        case 157028: // 100110010101100100
            return 9;
            break;
        case 208020: // 110010110010010100
            return 10;
            break;
        case 114548: // 011011111101110100
            return 11;
            break;
        case 72588:  // 010001101110001100
            return 12;
            break;
        case 231532: // 111000100001101100
            return 13;
            break;
    }
}

void qrReader::findFormat(center c1, center c2, center c3, QImage *img)
{
    int format = 0;
    int counter = 14;

    for (int col = 0; col < 8*pixelProportion; col += pixelProportion)
    {
        if (col != 6*pixelProportion)
        {
            if (isPixelBlack(c1.getRow()+(5*pixelProportion),c1.getCollumn()-(3*pixelProportion)+col, img))
                format += 1 << counter;
            counter--;
            paintPixel(c1.getRow()+(5*pixelProportion), c1.getCollumn()-(3*pixelProportion)+col, qRgb(0,0,255), img);
        }
    }

    for (int row = 0; row < 9*pixelProportion; row += pixelProportion)
    {
        if (row != 2*pixelProportion)
        {
            if (isPixelBlack(c1.getRow()+(5*pixelProportion)-row, c1.getCollumn()+(5*pixelProportion), img))
                format += 1 << counter;
            counter--;
            paintPixel(c1.getRow()+(5*pixelProportion)-row, c1.getCollumn()+(5*pixelProportion), qRgb(0,0,255), img);
        }
    }

    for (int row = 0; row < 7*pixelProportion; row += pixelProportion)
        paintPixel(c2.getRow()+(3*pixelProportion)-row, c2.getCollumn()+(5*pixelProportion), qRgb(0,0,255), img);

    for (int col = 0; col < 8*pixelProportion; col += pixelProportion)
        paintPixel(c3.getRow()+(5*pixelProportion), c3.getCollumn()-(4*pixelProportion)+col, qRgb(0,0,255), img);

    paintPixel(c2.getRow()-4*pixelProportion, c2.getCollumn()+5*pixelProportion, qRgb(0,0,255), img);

    eccLevel = 'L';
    switch (format) {
        case 30660:  // 111011111000100
            maskPatern = 0;
            break;
        case 29427:  // 111001011110011
            maskPatern = 1;
            break;
        case 32170:  // 111110110101010
            maskPatern = 2;
            break;
        case 30877:  // 111100010011101
            maskPatern = 3;
            break;
        case 26159:  // 110011000101111
            maskPatern = 4;
            break;
        case 25368:  // 110001100011000
            maskPatern = 5;;
            break;
        case 27713:  // 110110001000001
            maskPatern = 6;
            break;
        case 26998:  // 110100101110110
            maskPatern = 7;
            break;
    }
}

void qrReader::findQuietZone(center c1, center c2, center c3, QImage *img)
{
    int upperRow = c1.getRow()-4*pixelProportion;
    int leftCollumm = c1.getCollumn()-4*pixelProportion;
    int rigthCollumn = c2.getCollumn()+4*pixelProportion;
    int lowerRow = c3.getRow()+4*pixelProportion;

    for (int col = leftCollumm+pixelProportion; col < rigthCollumn; col += pixelProportion)
        paintPixel(upperRow, col, qRgb(0,0,0), img);
    for (int col = leftCollumm+pixelProportion; col < rigthCollumn; col += pixelProportion)
        paintPixel(lowerRow, col, qRgb(0,0,0), img);
    for (int row = upperRow+pixelProportion; row < lowerRow; row += pixelProportion)
        paintPixel(row, leftCollumm, qRgb(0,0,0), img);
    for (int row = upperRow+pixelProportion; row < lowerRow; row += pixelProportion)
        paintPixel(row, rigthCollumn, qRgb(0,0,0), img);
}

void qrReader::findAlignments(center c, QImage *img)
{
    for (int row = 0; row < 5*pixelProportion; row += pixelProportion)
    {
        for (int col = 0; col < 5*pixelProportion; col += pixelProportion)
        {
            if (versionINFO < 7)
                paintPixel(seed[versionINFO-2]*pixelProportion+virtualOriginRow-2*pixelProportion+row, seed[versionINFO-2]*pixelProportion+virtualOriginCol-2*pixelProportion+col, qRgb(255,0,0), img);
            else
            {
                paintPixel(seed2[versionINFO-7][0]*pixelProportion+virtualOriginRow-2*pixelProportion+row, seed2[versionINFO-7][1]*pixelProportion+virtualOriginCol-2*pixelProportion+col, qRgb(255,0,0), img);
                paintPixel(seed2[versionINFO-7][1]*pixelProportion+virtualOriginRow-2*pixelProportion+row, seed2[versionINFO-7][0]*pixelProportion+virtualOriginCol-2*pixelProportion+col, qRgb(255,0,0), img);
                paintPixel(seed2[versionINFO-7][1]*pixelProportion+virtualOriginRow-2*pixelProportion+row, seed2[versionINFO-7][1]*pixelProportion+virtualOriginCol-2*pixelProportion+col, qRgb(255,0,0), img);
                paintPixel(seed2[versionINFO-7][1]*pixelProportion+virtualOriginRow-2*pixelProportion+row, seed2[versionINFO-7][2]*pixelProportion+virtualOriginCol-2*pixelProportion+col, qRgb(255,0,0), img);
                paintPixel(seed2[versionINFO-7][2]*pixelProportion+virtualOriginRow-2*pixelProportion+row, seed2[versionINFO-7][1]*pixelProportion+virtualOriginCol-2*pixelProportion+col, qRgb(255,0,0), img);
                paintPixel(seed2[versionINFO-7][2]*pixelProportion+virtualOriginRow-2*pixelProportion+row, seed2[versionINFO-7][2]*pixelProportion+virtualOriginCol-2*pixelProportion+col, qRgb(255,0,0), img);
            }
        }
    }
}

void qrReader::unMask(int x, int y, QImage *img)
{
    int xAux = (x-virtualOriginRow)/pixelProportion;
    int yAux = (y-virtualOriginCol)/pixelProportion;
    switch (maskPatern) {
        case 0: // 000
            if ((xAux + yAux) % 2 == 0)
                reversePixel(x, y, img);
            break;
        case 1: // 001
            if (xAux % 2 == 0)
                reversePixel(x, y, img);
            break;
        case 2: // 010
            if (yAux % 3 == 0)
                reversePixel(x, y, img);
            break;
        case 3: // 011
            if ((xAux + yAux) % 3 == 0)
                reversePixel(x, y, img);
            break;
        case 4: // 100
            if ((xAux / 2 + yAux / 3) % 2 == 0)
                reversePixel(x, y, img);
            break;
        case 5: // 101
            if ((xAux * yAux) % 2 + (xAux * yAux) % 3 == 0)
                reversePixel(x, y, img);
            break;
        case 6: // 110
            if (((xAux * yAux) % 2 + (xAux * yAux) % 3) % 2 == 0)
                reversePixel(x, y, img);
            break;
        case 7: // 111
            if (((xAux * yAux) % 3 + (xAux + yAux) % 2) % 2 == 0)
                reversePixel(x, y, img);
            break;
        }
}

vector<int> qrReader::getDataBlocks(center c, QImage *img)
{
    vector<int> blocks;
    int word = 0;
    int blockCounter = 7;
    int lastCol = c.getCollumn()-3*pixelProportion;
    int lastRowUp = c.getRow()-13*pixelProportion-4*versionINFO*pixelProportion;
    int lastRowDown = c.getRow()+3*pixelProportion;
    int row = lastRowDown;
    int col = c.getCollumn()+13*pixelProportion+4*versionINFO*pixelProportion;

    while (col > lastCol)
    {
        if (row != lastRowUp)
        {
            while (row >= lastRowUp)
            {
                if (col == colTimming)
                {
                    col -= pixelProportion;
                }
                if (row == rowTimming)
                {
                    row -= pixelProportion;
                }
                for (int i = 0; i <= pixelProportion; i += pixelProportion)
                {
                    if (!isPattern(row, col-i, img))
                    {
                        unMask(row, col-i, img);
                        if (isPixelBlack(row, col-i, img))
                            word += 1 << blockCounter;
                        blockCounter--;
                        if (blockCounter == -1)
                        {
                            blocks.push_back(word);
                            word = 0;
                            blockCounter = 7;
                        }
                        //paintPixel(row,col-i,img);
                    }
                }
                row -= pixelProportion;
            }
            row += pixelProportion;
        }
        else
        {
            while (row <= lastRowDown)
            {
                if (col == colTimming)
                {
                    col -= pixelProportion;
                }
                if (row == rowTimming)
                {
                    row += pixelProportion;
                }
                for (int i = 0; i <= pixelProportion; i += pixelProportion)
                {
                    if (!isPattern(row, col-i, img))
                    {
                        unMask(row, col-i, img);
                        if (isPixelBlack(row, col-i, img))
                            word += 1 << blockCounter;
                        blockCounter--;
                        if (blockCounter == -1)
                        {
                            blocks.push_back(word);
                            word = 0;
                            blockCounter = 7;
                        }
                        //paintPixel(row,col-i,img);
                    }
                }
                row += pixelProportion;
            }
            row -= pixelProportion;
        }
        col -= 2*pixelProportion;
    }

    return correctDataBlocks(blocks);
}

vector<int> qrReader::correctDataBlocks(vector<int> dataBlocks)
{
    return dataBlocks;
}

String qrReader::decodeDataBlocks()
{
    int mode = (dataBlocks[0] & 240) >> 4;
    cout << "\nMODE = " << mode;
    int sizeDataLenght;
    if (versionINFO <= 9)
    {
        sizeDataLenght = (dataBlocks[0] & 15) << 4;
        sizeDataLenght += (dataBlocks[1]) >> 4;
    }
    else
    {
        sizeDataLenght = (dataBlocks[0] & 15) << 12;
        sizeDataLenght += (dataBlocks[1]) << 4;
        sizeDataLenght += (dataBlocks[2] & 240) >> 4;
    }
    cout << "\nNUMERO DE CARACTERES = " << sizeDataLenght;
    String data = "";
    switch (mode) {
        case NUMERIC_MODE:
            data = decodeNumeric(sizeDataLenght);
            break;
        case ALPHA_NUMERIC_MODE:
            data = decodeAlnum(sizeDataLenght);
            break;
        case BINARY_MODE:
            data = decodeBinary(sizeDataLenght);
            break;
        case JAPANESE_MODE:
            data = decodeJapanese(sizeDataLenght);
            break;
    }
    return data;
}

String qrReader::decodeNumeric(int sizeDataLenght)
{
    String data = "";
    return data;
}

String qrReader::decodeAlnum(int sizeDataLenght)
{
    String data = "";
    return data;
}

String qrReader::decodeBinary(int sizeDataLenght)
{
    int numBlock;
    if (versionINFO <= 9)
        numBlock = 1;
    else
        numBlock = 2;
    int intData;
    String data = "";
    for (int i = 0; i < sizeDataLenght; i++)
    {
        intData = (dataBlocks[numBlock] & 15) << 4;
        intData += (dataBlocks[numBlock+1]) >> 4;
        numBlock++;
        data += (char) intData;
    }

    return data;
}

String qrReader::decodeJapanese(int sizeDataLenght)
{
    String data = "";
    return data;
}

bool qrReader::isPixelBlack(int row, int col, QImage *img)
{
    return (qGray(img->pixel(QPoint(col,row))) < 128);
}

void qrReader::paintPixel(int row, int col, QRgb color, QImage *img)
{
    img->setPixel(QPoint(col, row), color);
}

void qrReader::reversePixel(int row, int col, QImage *img)
{
    if (qGray(img->pixel(QPoint(col,row))) < 128)
        img->setPixel(QPoint(col, row), qRgb(255,255,255));
    else
        img->setPixel(QPoint(col, row), qRgb(0,0,0));
}

bool qrReader::isPattern(int row, int col, QImage *img)
{
    if ((img->pixel(QPoint(col,row)) == qRgb(0,255,0)))
        return true;
    if ((img->pixel(QPoint(col,row)) == qRgb(0,0,255)))
        return true;
    if ((img->pixel(QPoint(col,row)) == qRgb(32,255,200)))
        return true;
    if ((img->pixel(QPoint(col,row)) == qRgb(255,0,0)))
        return true;
    return false;
}
